package com.ficus.road.maintain.service;

import com.alibaba.fastjson.JSON;
import com.aliyun.oss.model.OSSObject;
import com.ficus.road.maintain.core.model.Hit;
import com.ficus.road.maintain.operationlog.annotation.OpLog;
import com.ficus.road.maintain.util.AliyunOSSUtil;
import com.ficus.road.maintain.util.ImageUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author hao.zhou1
 * @date 2021/12/17 下午7:42
 */
@Component
@Slf4j
public class CjyhClient {

    @Value("${push.cjyh.token_url}")
    private String tokenUrl;
    @Value("${push.cjyh.url}")
    private String url;
    @Value("${push.cjyh.grant_type}")
    private String grantType;
    @Value("${push.cjyh.username}")
    private String username;
    @Value("${push.cjyh.password}")
    private String password;
    @Value("${push.cjyh.client_id}")
    private String clientId;
    @Value("${push.cjyh.client_secret}")
    private String clientSecret;
    @Value("#{'${push.cjyh.car_id}'.split(',')}")
    private List<String> carIds;
    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private AliyunOSSUtil aliyunOSSUtil;

    public boolean isSupport(String carId) {
        return carIds.contains(carId);
    }

    private String getToken() {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "application/x-www-form-urlencoded");
        MultiValueMap<String, Object> postParameters = new LinkedMultiValueMap<>();
        postParameters.add("username", username);
        postParameters.add("password", password);
        postParameters.add("client_id", clientId);
        postParameters.add("client_secret", clientSecret);
        postParameters.add("grant_type", grantType);
        HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<>(postParameters, headers);
        ResponseEntity<Map> mapResponseEntity = restTemplate.postForEntity(tokenUrl, httpEntity, Map.class);
        if (mapResponseEntity.getStatusCode().equals(HttpStatus.OK) && StringUtils.isNotBlank(mapResponseEntity.getBody().get("access_token").toString())) {
            return mapResponseEntity.getBody().get("access_token").toString();
        }
        return null;
    }

    @OpLog(description = "推送城建养护")
    public boolean pushHit(Hit hit) {
        String token = getToken();
        if (StringUtils.isNotBlank(token)) {
            Map<String, Object> requestBody = parseToRequestBody(hit);
            HttpHeaders headers = new HttpHeaders();
            headers.add("Content-Type", "application/json");
            headers.add("Authorization", "bearer " + token);
            HttpEntity<Map<String, Object>> httpEntity = new HttpEntity<>(requestBody, headers);
            ResponseEntity<String> mapResponseEntity = restTemplate.postForEntity(url, httpEntity, String.class);
            if (mapResponseEntity.getStatusCode().equals(HttpStatus.OK) && JSON.parseObject(mapResponseEntity.getBody()).get("Success").equals(true)) {
                return true;
            }
        }
        return false;
    }

    private Map<String, Object> parseToRequestBody(Hit hit) {
        Map<String, Object> map = new HashMap<>();
        String frameImageUrl = hit.getAttrs().getFrameImageUrl();
        if (StringUtils.isBlank(frameImageUrl)) {
            frameImageUrl = hit.getAttrs().getSceneImage();
        }
        String originImageBase64 = null;
        try {
            OSSObject imageOssFile = aliyunOSSUtil.getFileByUrl(frameImageUrl);
            byte[] originImageBytes = imageOssFile.getObjectContent().readAllBytes();
            originImageBase64 = ImageUtil.bytes2Base64(originImageBytes);
        } catch (IOException e) {
            log.error("get image met exception:", e);
        }
        map.put("id", hit.getId());
        map.put("type", hit.getType());
        map.put("longitude", hit.getAttrs().getGpsLocation().getLongitude());
        map.put("latitude", hit.getAttrs().getGpsLocation().getLatitude());
        map.put("time", new Date().getTime() / 1000);
        map.put("picture", "data:image/jpg;base64," + originImageBase64);
        String roadName = hit.getAttrs().getRoadName();
        String[] split = roadName.split(",");
        map.put("roadName", split[0]);
        if (hit.getLength() != null && hit.getLength() > 0) {
            map.put("length", hit.getLength());
        }
        if (hit.getWidth() != null && hit.getWidth() > 0) {
            map.put("width", hit.getWidth());
        }
        if (hit.getHeightDiff() != null && hit.getHeightDiff() > 0) {
            map.put("heightDiff", hit.getHeightDiff());
        }
        if (hit.getArea() != null && hit.getArea() > 0) {
            map.put("area", hit.getArea());
        }
        return map;
    }
}
